home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Technical Documentation / PCI Information / PCI Developer’s Kit (disk) / PCI Testing / PCITest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-27  |  12.3 KB  |  379 lines  |  [TEXT/MPS ]

  1. /*
  2. *
  3. * © Copyright 1994, Apple Computer, Inc.
  4. *
  5. * by Rob Glanville
  6. *
  7. * 30 Mar 94
  8. *
  9. * PCITest.c - tests for PCI compliance
  10. *
  11. * PCITest.c is a simple test for PCI configuration space compliance testing. It writes and reads
  12. * various config space registers and checks them for expected values according to the current
  13. * PCI specification. There are a few routines that are hardware dependent and those must be
  14. * supplied by the user. To use the test, simply add in the hardware specific code, compile
  15. * it on your target machine, and run it as an application.
  16. *
  17. * This is a first pass of the test suite.
  18. */
  19.  
  20. #include <stdio.h>
  21.  
  22.  
  23. #define UInt8        unsigned char
  24. #define UInt16        unsigned short
  25. #define UInt32        unsigned long
  26. #define    PInt8        *(UInt8 *)            /* Used for physical address casting */
  27. #define    PInt16        *(UInt16 *)            /* Used for physical address casting */
  28. #define    PInt32        *(UInt32 *)            /* Used for physical address casting */
  29. #define True        0xffffffff
  30. #define False        0x00000000
  31. #define    Null        False                /* Nothing but trouble */
  32.  
  33. /* Configuration space register offsets */
  34. #define    PCI_VendorID        0x0000
  35. #define PCI_DeviceID        0x0002
  36. #define    PCI_Command            0x0004
  37. #define PCI_Status            0x0006
  38. #define    PCI_RevisionID        0x0008
  39. #define PCI_ClassCode        0x0009
  40. #define PCI_CacheLineSize    0x000c
  41. #define    PCI_LatencyTimer    0x000d
  42. #define    PCI_HeaderType        0x000e
  43. #define    PCI_BIST            0x000f
  44. #define    PCI_BaseAddress0    0x0010
  45. #define    PCI_BaseAddress1    0x0014
  46. #define    PCI_BaseAddress2    0x0018
  47. #define    PCI_BaseAddress3    0x001c
  48. #define    PCI_BaseAddress4    0x0020
  49. #define    PCI_BaseAddress5    0x0024
  50. #define PCI_Reserved1        0x0028
  51. #define PCI_Reserved2        0x002c
  52. #define    PCI_ExpansionROM    0x0030
  53. #define PCI_Reserved3        0x0034
  54. #define PCI_Reserved4        0x0038
  55. #define    PCI_InterruptLine    0x003c
  56. #define    PCI_InterruptPin    0x003d
  57. #define    PCI_Min_Gnt            0x003e
  58. #define    PCI_Max_Lat            0x003f
  59.  
  60. UInt8  Data8;
  61. UInt16 Data16;
  62. UInt32 Data32;
  63.  
  64. extern void   printstr(const char *);
  65. extern void   outchar(UInt8);
  66. extern void   byteout(UInt8);
  67. extern void   wordout(UInt16);
  68. extern void   longout(UInt32);
  69. extern void   crlf();
  70.  
  71. /*
  72.     The following external routines are localized hardware dependent
  73.     abstraction layers that provide access to physical or simulated hardware
  74. */
  75. extern UInt8 GetPresentsBits(); /* Returns the two presents bits in bits 0 and 1 of byte */
  76.  
  77. /* Access to PCI configuration space is hardware dependent */
  78. extern UInt8  Read8_Config  (UInt32 RegisterOffset);
  79. extern void   Write8_Config (UInt32 RegisterOffset,UInt8  Data);
  80. extern UInt16 Read16_Config (UInt32 RegisterOffset);
  81. extern void   Write16_Config(UInt32 RegisterOffset,UInt16 Data);
  82. extern UInt32 Read32_Config (UInt32 RegisterOffset);
  83. extern void   Write32_Config(UInt32 RegisterOffset,UInt32 Data);
  84.  
  85. /**************************************** Utilities **************************************/
  86.  
  87. void PutPass() {
  88.     printf(" passed\n");
  89.     }
  90.  
  91. void PutFail() {
  92.     printf(" #####> FAILED <#####\n");
  93.     }
  94.  
  95. void PutSkip() {
  96.     printf(" * skipped *\n");
  97.     }
  98.  
  99. #define watt25    0x01
  100. #define watt15    0x02
  101. #define    watt7_5    0x00
  102.  
  103. /*
  104.  Get the two presents bits from external hardware interface code
  105.  for the unit under test
  106. */
  107. UInt8 UnitUnderTestPresent() {
  108.     UInt8 presentbits;
  109.     presentbits = GetPresentsBits();
  110.     if ((presentbits & 0x03) != 0x03) {
  111.         printf("Presents bits = %02x for ",presentbits);
  112.         if (presentbits == watt25) printf("25 watts");
  113.         else if (presentbits == watt15) printf("15 watts");
  114.         else printf("7.5 watts\n");
  115.         return(True);
  116.         }
  117.     else {
  118.         printf("** No card was found\n");
  119.         return(False);
  120.         }
  121.     }
  122.  
  123. void DisplayConfiguration() {
  124.     Data32 = Read32_Config(PCI_VendorID); /* Read the ID registers */
  125.     printf("Vendor ID        = %04x\n",(Data32 & 0x0000ffff));
  126.     printf("Device ID        = %04x\n",(Data32 >> 16) & 0x0000ffff);
  127.     Data32 = Read32_Config(PCI_Command); /* Read the command and status registers */
  128.     printf("Command          = %04x\n",(Data32 & 0x0000ffff));
  129.     printf("Status           = %04x\n",(Data32 >> 16) & 0x0000ffff);
  130.     Data32 = Read32_Config(PCI_RevisionID); /* Read the Revision registers */
  131.     printf("Base class       = %02x, Sub-class = %02x, Interface = %02x\n",(Data32 >> 24) & 0x00000ff,(Data32 >> 16) & 0x00000ff,(Data32 >> 8) & 0x00000ff);
  132.     printf("Revision         = %02x\n",(Data32 & 0x00000ff));
  133.     Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
  134.     printf("BIST             = %02x\n",(Data32 >> 24) & 0x00000ff);
  135.     printf("Header type      = %02x\n",(Data32 >> 16) & 0x00000ff);
  136.     printf("Latency          = %02x\n",(Data32 >> 8) & 0x00000ff);
  137.     printf("Cache line size  = %02x\n",(Data32 & 0x00000ff));
  138.     Data32 = Read32_Config(PCI_BaseAddress0); /* Read the base address registers */
  139.     printf("Base addr 0      = %08x\n",(Data32));
  140.     Data32 = Read32_Config(PCI_BaseAddress1); /* Read the base address registers */
  141.     printf("Base addr 1      = %08x\n",(Data32));
  142.     Data32 = Read32_Config(PCI_BaseAddress2); /* Read the base address registers */
  143.     printf("Base addr 2      = %08x\n",(Data32));
  144.     Data32 = Read32_Config(PCI_BaseAddress3); /* Read the base address registers */
  145.     printf("Base addr 3      = %08x\n",(Data32));
  146.     Data32 = Read32_Config(PCI_BaseAddress4); /* Read the base address registers */
  147.     printf("Base addr 4      = %08x\n",(Data32));
  148.     Data32 = Read32_Config(PCI_BaseAddress5); /* Read the base address registers */
  149.     printf("Base addr 5      = %08x\n",(Data32));
  150.     Data32 = Read32_Config(PCI_ExpansionROM); /* Read the expansion ROM address register */
  151.     printf("ROM base         = %08x\n",(Data32));
  152.     Data32 = Read32_Config(PCI_InterruptLine); /* Read registers */
  153.     printf("Max_Lat          = %02x\n",(Data32 >> 24) & 0x00000ff);
  154.     printf("Min_Gnt          = %02x\n",(Data32 >> 16) & 0x00000ff);
  155.     printf("Interrupt pin    = %02x\n",(Data32 >> 8) & 0x00000ff);
  156.     printf("Interrupt line   = %02x\n",(Data32 & 0x000000ff));
  157.     }
  158.  
  159. /* Check that Vendor ID is not equal to 0xffff */
  160. void VendorIDCheck(){
  161.     printf("Vendor ID Check.......................");
  162.     Data32 = Read16_Config(PCI_VendorID); /* Read the ID register */
  163.     Data16 = Data32 & 0x0000ffff;
  164.     if (Data16 == 0xffff) PutFail();
  165.     else PutPass();
  166.     }
  167.  
  168. /* Check that Device ID is not equal to 0xffff */
  169. void DeviceIDCheck(){
  170.     printf("Device ID Check.......................");
  171.     Data32 = Read32_Config(PCI_VendorID); /* Read the ID register */
  172.     Data16 = (Data32 >> 16) & 0x0000ffff;
  173.     if (Data16 == 0xffff) PutFail();
  174.     else PutPass();
  175.     }
  176.  
  177. void CommandCheck(){
  178.     printf("Command bits Check....................");
  179.     PutSkip();
  180.     }
  181.     
  182. void StatusCheck(){
  183.     printf("Status bits Check.....................");
  184.     PutSkip();
  185.     }
  186.  
  187. /* Check for proper class code values */
  188. void ClassCodeCheck() {
  189.     UInt8 BaseClass,SubClass,ProgramInterface,FailureFlag;
  190.     printf("Class code Check......................");
  191.     FailureFlag = False;
  192.     Data32 = Read32_Config(PCI_RevisionID); /* Read the class code registers */
  193.     BaseClass            = (Data32 >> 24) & 0x000000ff;
  194.     SubClass            = (Data32 >> 16) & 0x000000ff;
  195.     ProgramInterface    = (Data32 >>  8) & 0x000000ff;
  196.     if (BaseClass > 6) FailureFlag = True; /* Only six classes defined so far */
  197.     else if (ProgramInterface > 0) FailureFlag = True; /* Only one program interface */
  198.     else switch(BaseClass) {
  199.         case 0: /* Pre class code devices */
  200.             if (SubClass > 1) FailureFlag = True;
  201.             break;
  202.         case 1:
  203.             if ((SubClass > 3) && (SubClass != 0x80)) FailureFlag = True;
  204.             break;
  205.         case 2:
  206.             if ((SubClass > 2) && (SubClass != 0x80)) FailureFlag = True;
  207.             break;
  208.         case 3:
  209.             if ((SubClass > 1) && (SubClass != 0x80)) FailureFlag = True;
  210.             break;
  211.         case 4:
  212.             if ((SubClass > 1) && (SubClass != 0x80)) FailureFlag = True;
  213.             break;
  214.         case 5:
  215.             if ((SubClass > 1) && (SubClass != 0x80)) FailureFlag = True;
  216.             break;
  217.         case 6:
  218.             if ((SubClass > 5) && (SubClass != 0x80)) FailureFlag = True;
  219.             break;
  220.             }
  221.     if (FailureFlag) PutFail();
  222.     else PutPass();
  223.     }
  224.  
  225. /* Check that revision register is not equal to 0xff */
  226. void RevisionCheck(){
  227.     UInt8 Revision;
  228.     printf("Revision Check........................");
  229.     Data32 = Read32_Config(PCI_RevisionID); /* Read the Revision register */
  230.     Revision = Data32 & 0x000000ff;
  231.     if (Revision == 0xff) PutFail();
  232.     else PutPass();
  233.     }
  234.     
  235. void BISTCheck(){
  236.     UInt8 BIST,FailureFlag;
  237.     UInt32 timer;
  238.     printf("BIST Check............................");
  239.     Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
  240.     FailureFlag = False;
  241.     BIST = (Data32 >> 24) & 0x00000ff;
  242.     if ((BIST & 0x80) == 0x80) { /* Support built in self test, Let's run it */
  243.         Write32_Config(PCI_CacheLineSize,0x40000000); /* Start test */
  244.         timer = 0x80000;while(--timer); /* Delay for test to complete */
  245.         Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
  246.         BIST = (Data32 >> 24) & 0x00000ff;
  247.         if ((BIST & 0x0f) != 0x00) FailureFlag = True; /* Did test fail? */
  248.         }
  249.     if (FailureFlag) PutFail();
  250.     else PutPass();
  251.     }
  252.  
  253. /* Check that the header type is zero */
  254. void HeadTypeCheck(){
  255.     UInt8 HeaderType;
  256.     printf("Header type Check.....................");
  257.     Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
  258.     HeaderType = (Data32 >> 16) & 0x00000ff;
  259.     if (HeaderType != 0x00) PutFail();
  260.     else PutPass();
  261.     }
  262.     
  263. void LatencyTimerCheck(){
  264.     UInt8 Latency;
  265.     printf("Latency timer Check...................");
  266.     Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
  267.     Latency = (Data32 >> 8) & 0x00000ff;
  268.     PutSkip();
  269.     }
  270.     
  271. void CacheLineCheck(){
  272.     UInt8 CacheLineSize;
  273.     printf("Cache line Check......................");
  274.     Data32 = Read32_Config(PCI_CacheLineSize); /* Read the registers */
  275.     CacheLineSize = (Data32 & 0x00000ff);
  276.     PutSkip();
  277.     }
  278.     
  279. void BaseRegistersCheck(){
  280.     printf("Base registers Check..................");
  281.     PutSkip();
  282.     }
  283.  
  284. /* Check that the reserve registers are zero and can't be changed */
  285. void ReservedRegistersCheck(){
  286.     UInt8 FailureFlag;
  287.     UInt32 ResData1,ResData2,ResData3,ResData4;
  288.     printf("Reserved registers Check..............");
  289.     FailureFlag = False;
  290.     ResData1 = Read32_Config(PCI_Reserved1); /* Read a reserved register */
  291.     ResData2 = Read32_Config(PCI_Reserved2); /* Read a reserved register */
  292.     ResData3 = Read32_Config(PCI_Reserved3); /* Read a reserved register */
  293.     ResData4 = Read32_Config(PCI_Reserved4); /* Read a reserved register */
  294.     if ( (ResData1 != Null) &&
  295.          (ResData2 != Null) &&
  296.          (ResData3 != Null) &&
  297.          (ResData4 != Null) ) FailureFlag = True;
  298.     Write32_Config(PCI_Reserved1,0xffffffff); /* Write a reserved register */
  299.     Write32_Config(PCI_Reserved2,0xffffffff); /* Write a reserved register */
  300.     Write32_Config(PCI_Reserved3,0xffffffff); /* Write a reserved register */
  301.     Write32_Config(PCI_Reserved4,0xffffffff); /* Write a reserved register */
  302.     ResData1 = Read32_Config(PCI_Reserved1); /* Read a reserved register */
  303.     ResData2 = Read32_Config(PCI_Reserved2); /* Read a reserved register */
  304.     ResData3 = Read32_Config(PCI_Reserved3); /* Read a reserved register */
  305.     ResData4 = Read32_Config(PCI_Reserved4); /* Read a reserved register */
  306.     if ( (ResData1 != Null) &&
  307.          (ResData2 != Null) &&
  308.          (ResData3 != Null) &&
  309.          (ResData4 != Null) ) FailureFlag = True;
  310.     if (FailureFlag) PutFail();
  311.     else PutPass();
  312.     }
  313.     
  314. void ExpansionROMCheck(){
  315.     printf("Expansion ROM Check...................");
  316.     PutSkip();
  317.     }
  318.     
  319. void InterruptLineCheck(){
  320.     printf("Interrupt line Check..................");
  321.     PutSkip();
  322.     }
  323.     
  324. void InterruptPinCheck(){
  325.     printf("Interrupt pin Check...................");
  326.     PutSkip();
  327.     }
  328.     
  329. void MinGrantCheck(){
  330.     UInt8 MinimumGrant;
  331.     float InMicroseconds;
  332.     printf("Minimum grant Check...................");
  333.     MinimumGrant = (Data32 >> 24) & 0x00000ff;
  334.     if (MinimumGrant > 0) {
  335.         InMicroseconds = 0.25 * MinimumGrant;
  336.         printf(" %02.2f microseconds\n",InMicroseconds);
  337.         }
  338.     else printf(" passed, No minimum grant requirements\n");
  339.     }
  340.     
  341. void MaxLatencyCheck(){
  342.     UInt8 MaximumLatency;
  343.     float InMicroseconds;
  344.     printf("Maximum latency Check.................");
  345.     Data32 = Read32_Config(PCI_InterruptLine); /* Read registers */
  346.     MaximumLatency = (Data32 >> 24) & 0x00000ff;
  347.     if (MaximumLatency > 0) {
  348.         InMicroseconds = 0.25 * MaximumLatency;
  349.         printf(" %02.2f microseconds\n",InMicroseconds);
  350.         }
  351.     else printf(" passed, No latency requirements\n");
  352.     }
  353.     
  354.  
  355. void PCIComplianceTest(){
  356.     if (UnitUnderTestPresent()) {
  357.         DisplayConfiguration();
  358.         VendorIDCheck();
  359.         DeviceIDCheck();
  360.         CommandCheck();
  361.         StatusCheck();
  362.         ClassCodeCheck();
  363.         RevisionCheck();
  364.         BISTCheck();
  365.         HeadTypeCheck();
  366.         LatencyTimerCheck();
  367.         CacheLineCheck();
  368.         BaseRegistersCheck();
  369.         ReservedRegistersCheck();
  370.         ExpansionROMCheck();
  371.         InterruptLineCheck();
  372.         InterruptPinCheck();
  373.         MinGrantCheck();
  374.         MaxLatencyCheck();
  375.         }
  376.     }
  377.  
  378. /************************************* End of PCI Tests *************************************/
  379.